package com.yang.job.admin.infra.event.schema;

import com.google.common.eventbus.Subscribe;
import com.yang.job.admin.client.dto.common.BusinessException;
import com.yang.job.admin.client.dto.common.ErrorCode;
import com.yang.job.admin.infra.event.EventCenter;
import com.yang.job.admin.infra.event.IEventHandler;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component
public class EventBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (!(bean instanceof IEventHandler)) {
            return bean;
        }
        Method subscribeMethod = getSubscribeMethod(bean);
        Class<?>[] parameterTypes = subscribeMethod.getParameterTypes();
        String eventName = parameterTypes[0].getName();
        EventCenter.registerEventHandler(eventName, (IEventHandler) bean);
        return bean;
    }

    private Method getSubscribeMethod(Object bean) {
        Method[] methods = bean.getClass().getDeclaredMethods();
        Method subscribeMethod = null;
        int subscribeCount = 0;
        for (Method method : methods) {
            if (!method.isAnnotationPresent(Subscribe.class)) {
                continue;
            }
            Class<?>[] parameterTypes = method.getParameterTypes();
            if (parameterTypes.length > 1) {
                continue;
            }
            if (parameterTypes[0].isInterface()) {
                continue;
            }
            ++ subscribeCount;
            subscribeMethod = method;
        }
        if (subscribeCount == 0) {
            throw new BusinessException(ErrorCode.EVENT_HANDLE_NOT_SUBSCRIBE);
        } else if (subscribeCount > 1) {
            throw new BusinessException(ErrorCode.EVENT_HANDLE_SUBSCRIBE_TOO_MANY_METHOD);
        }
        return subscribeMethod;
    }
}
